package zombiegame;

import java.util.Iterator;
import java.util.List;

import graphics.Field;
import graphics.Location;

/**
 * Zombie class, derives from Character.
 * @author pylaffon
 *
 */
public class Zombie extends Character {
    /**
     * Constructor of Zombie class.
     * @param name name of the character
     * @param healthPoints initial HP
     */
    public Zombie(String name, int healthPoints, Field field, Location location) {
        super(name, healthPoints, field, location, TypeCharacter.Zombie);
    }
    /**
     * Output a character's saying to the screen
     * @param str what the character says
     */
    public void say(String str) {
        System.out.println(name + " says: BRAIIIIIINS!");
    }
    /**
     * Method triggered on each character at the end of each turn.
     */
    public void endOfTurn() {

        Location newLocation = findEnnemi(location);
        if (newLocation != null) {
            Character c = (Character)field.getObjectAt(newLocation);
            this.encounterCharacter(c);
            newLocation = null;
        }

        if (newLocation == null) {
            // No food found - try to move to a free location.
            newLocation = field.freeAdjacentLocation(location);
        }
        // See if it was possible to move.
        if (newLocation != null) {
            setLocation(newLocation);
        } else {
            // Overcrowding.
            setDead();
        }
    }

    /**
     * Tell the fox to look for rabbits adjacent to its current location. Only
     * the first live rabbit is eaten.
     * 
     * @param location
     *            Where in the field it is located.
     * @return Where food was found, or null if it wasn't.
     */
    private Location findEnnemi(Location location) {
        List<Location> adjacent = field.adjacentLocations(location);
        Iterator<Location> it = adjacent.iterator();
        while (it.hasNext()) {
            Location where = it.next();
            Object object = field.getObjectAt(where);
            if (object instanceof Character) {
                Character character = (Character) object;
                if (character.getType() == TypeCharacter.Human || character.getType() == TypeCharacter.Vampire) {
                    return where;
                }
            }
        }
        return null;
    }

    /**
     * Method called when a vampire decides to attack a character
     * @param c the other character that this vampire attacks
     */
    protected void attack(Character c) {
        c.reduceHealthPoints(5);
        if (c.getType() == TypeCharacter.Human && c.getHealthPoints() < 1) {
            ((Human)c).setHasBeenKilled(true);
        }
    }


    /**
     * Method triggered when the zombie described by the current object
     * meets another character, and does something to him (for example, attack).
     * @param c the other character that this character meets
     */
    public void encounterCharacter(Character c) {
        // Attack if the enemy is human or vampire (then 50% chance)
        if (c.getType() == TypeCharacter.Human || (c.getType() == TypeCharacter.Vampire && Simulator.GenerateRandomBoolean())) {
            //super.say(c.getName() + ", I'm gonna kill you!! " + this.getHealthPoints()); // want Character#say not Zombie#say
            attack(c);
        }
    }
}
